import requests
import time
import hmac
import hashlib
import base64
from django.conf import settings


class DingTalkSNSClient:
    def __init__(self):
        self.app_key = settings.DINGTALK_APP_KEY
        self.app_secret = settings.DINGTALK_APP_SECRET
        self.get_user_info_url = "https://oapi.dingtalk.com/sns/getuserinfo_bycode"

    def _generate_signature(self, timestamp):
        """生成签名（仅Base64编码，不手动URL编码）"""
        sign_data = timestamp  # 必须是字符串类型的毫秒级时间戳
        hmac_obj = hmac.new(
            key=self.app_secret.encode("utf-8"),
            msg=sign_data.encode("utf-8"),
            digestmod=hashlib.sha256
        )
        # 仅进行Base64编码，URL编码由requests自动处理
        return base64.b64encode(hmac_obj.digest()).decode("utf-8")

    def get_user_info_by_code(self, tmp_auth_code):
        try:
            timestamp = str(int(time.time() * 1000))  # 13位毫秒级时间戳（字符串）
            print(f"timestamp: {timestamp}")

            signature = self._generate_signature(timestamp)
            print(f"原始签名（Base64）: {signature}")  # 打印未编码的原始签名

            # 构造参数（不手动编码signature）
            params = {
                "accessKey": self.app_key,
                "timestamp": timestamp,
                "signature": signature  # 直接传递Base64签名
            }
            json_data = {"tmp_auth_code": tmp_auth_code}

            response = requests.post(
                url=self.get_user_info_url,
                params=params,  # requests会自动对signature进行URL编码
                json=json_data,
                timeout=10
            )
            print(f"实际请求URL: {response.url}")  # 确认签名仅被编码一次

            response_data = response.json()
            print(f"钉钉接口返回: {response_data}")

            if response_data.get("errcode") != 0:
                raise Exception(
                    f"钉钉接口错误: {response_data.get('errmsg')}（错误码：{response_data.get('errcode')}）"
                )
            return response_data["user_info"]

        except Exception as e:
            raise Exception(f"获取钉钉用户信息失败: {str(e)}")